週期性特徵(Cyclical Features)又稱循環性特徵,是指資料會遵循某種週期,重複循環。風向、季節、時間等都是週期性變數。如何讓模型正確解讀出23:00到01:00是相差2小時,而不是相差22小時?23:00和4:30哪個較接近01:00?我們必須保留這個循環性資訊在資料集裡,如此,機器學習模型才能做出正確學習。
循環性的事物有重複性,也就是有個分母(1天的總小時數或1小時總秒數),所以,我們可以運用同樣有重複行為的函數sin和cos,建立兩個新的週期性特徵。
公式如下:
資料來源:https://www.thedataschool.com.au/ryan-edwards/feature-engineering-cyclical-variables/
以24小時為例,max(a)就是24,將中午12點a=12,帶入公式,它的x=0,y=1,當我們依序算出所有小時的x、y值,再把這些值標記在座標圖上,就可以清楚看出23:00和4:30哪個較接近01:00。
我們可以到這個網站https://www.random.org/clock-times/ 抓取一些資料並將它存到CSV檔。
import numpy as np
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
df = pd.read_csv('../input/times09222020/Times.csv')
df['Time'] = pd.to_datetime(df['Time'])
df['hour'] = df['Time'].dt.hour
df['minute'] = df['Time'].dt.minute
df.head()
/|Time| hour| minute
------------- | -------------
0| 2020-09-22 00:10:00| 0 |10
1| 2020-09-22 00:20:00| 0| 20
2| 2020-09-22 00:30:00| 0 |30
3| 2020-09-22 00:40:00 |0| 40
4| 2020-09-22 00:50:00 |0| 5
對"hour"變數建立x、y兩個新的特徵,及繪製座標圖。
df['x']=np.sin(2.*np.pi * df.hour/24.)
df['y']=np.cos(2.*np.pi * df.hour/24.)
print(df)
df.plot.scatter('x','y').set_aspect('equal')
/|Time| hour| minute| x | y
------------- | -------------
0| 2020-09-22 00:10:00| 0 | 10 | 0.000000| 1.000000
1 | 2020-09-22 00:20:00 | 0 | 20| 0.000000| 1.000000
2| 2020-09-22 00:30:00| 0 | 30| 0.000000 | 1.000000
3| 2020-09-22 00:40:00| 0 | 40| 0.000000| 1.000000
4| 2020-09-22 00:50:00| 0 | 50 | 0.000000 | 1.000000
.. | ...| ... | ... | ... | ...
95| 2020-09-22 22:50:00 | 22 | 50 |-0.500000 | 0.866025
96| 2020-09-22 23:10:00 | 23 | 10| -0.258819 | 0.965926
97 |2020-09-22 23:20:00 | 23 | 20| -0.258819| 0.965926
98| 2020-09-22 23:30:00 | 23| 30 |-0.258819 | 0.965926
99| 2020-09-22 23:50:00 | 23 | 50| -0.258819| 0.965926
[100 rows x 5 columns]
以小時為單位將分鐘轉換成小數,計算所有資料的x、y值及繪製座標圖。
df['hourfloat']=df.hour+df.minute/60.0
df['x']=np.sin(2.*np.pi*df.hourfloat/24.)
df['y']=np.cos(2.*np.pi*df.hourfloat/24.)
df
df.plot.scatter('x','y').set_aspect('equal')
/|Time| hour | minute| hourfloat | x | y
------------- | -------------
0 | 2020-09-22 00:10:00| 0 | 10| 0.166667 | 0.043619 | 0.999048
1 | 2020-09-22 00:20:00 | 0 | 20| 0.333333| 0.087156| 0.996195
2 | 2020-09-22 00:30:00| 0 | 30| 0.500000| 0.130526| 0.991445
3 | 2020-09-22 00:40:00| 0 | 40 | 0.666667| 0.173648 | 0.984808
4 | 2020-09-22 00:50:00| 0| 50 | 0.833333| 0.216440 | 0.976296
..| ...| ... | ...| ... | ... | ...
95| 2020-09-22 22:50:00| 22 | 50| 22.833333| -0.300706 | 0.953717
96| 2020-09-22 23:10:00| 23 | 10| 23.166667| -0.216440| 0.976296
97 |2020-09-22 23:20:00| 23 | 20| 23.333333| -0.173648| 0.984808
98 |2020-09-22 23:30:00| 23 | 30| 23.500000| -0.130526 | 0.991445
99| 2020-09-22 23:50:00 | 23 | 50 | 23.833333| -0.043619| 0.999048
[100 rows x 6 columns]